//Server.java  
//
//Copyright (C) 2008 Devon Mizelle  
//  
//This program is distributed in the hope that it will be useful,  
//but WITHOUT ANY WARRANTY; without even the implied warranty of  
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
//GNU General Public License for more details.  
//  
//You should have received a copy of the GNU General Public License  
//along with this program.  If not, see <http://www.gnu.org/licenses/>.
package hermes; 
import java.net.ServerSocket;
import java.net.Socket;
import java.io.ObjectOutputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.FileInputStream;
import java.io.File;
import java.util.ArrayList;

/**
 * @author Devon Mizelle
 */
public class Server extends Thread
{
    private ServerSocket sSocket = null;
    private final String VERSION = "svn1";
    private File file = null;
    private FileInputStream fis = null;
    private FileOutputStream fos = null;
    private ObjectOutputStream oos = null;
    private ObjectInputStream ois = null;
    private UserMap userMap = null;
    private ArrayList connectionList = null;
    public static void main(String[] args){
        try{
            new Server(Integer.parseInt(args[0]));
        }
        catch(ArrayIndexOutOfBoundsException e){
            new Server(9001);
        }
    }
    
    
    public Server(int port){
        connectionList = new ArrayList<ServerThread>();
        try{sSocket = new ServerSocket(port);}
        catch(Exception e){e.printStackTrace();}
        System.out.println("Hermes Server version " + VERSION + " started on"
                + " port " + port + ".");
        System.out.println("Creating/Loading UserMap...");
        initUserMap();
        start();
    }
    public void run(){
        while(true){
            try{
                
                Socket sock = sSocket.accept();
                ServerThread st = new ServerThread(sock, this);
                connectionList.add(st);
                st.start();
            }
        
            catch(Exception e){
                e.printStackTrace();
            }
       }
//       try{sSocket.close();}
//       catch(Exception e){e.printStackTrace();}
        
        
    }
    
    public void initUserMap(){
        File file = new File("user.map");
        if(!file.exists()){
            try{
                file.createNewFile();
                UserMap um = new UserMap();
                FileOutputStream fosR = new FileOutputStream(file);
                ObjectOutputStream oosR = new ObjectOutputStream(fosR);
                oosR.writeObject(um);
                oosR.flush();
                fosR.flush();
                oosR.close();
                fosR.close();
            }
            catch(Exception e){
                e.printStackTrace();
                System.exit(1);
            }
        }
        try{fos = new FileOutputStream(file, true);
        oos = new ObjectOutputStream(fos);
        fis = new FileInputStream(file);
        ois = new ObjectInputStream(fis);}catch(Exception e){e.printStackTrace();}

        try {
            userMap = (UserMap) ois.readObject();
        }
        catch(Exception e){
            e.printStackTrace();
            System.exit(1);
        }
        try{ois.close(); fis.close(); oos.close(); fos.close();}
        catch(Exception e){e.printStackTrace();}
        
        
        
    }
    
    public void addUser(User user) {
        userMap.put((String)user.get("id"), user);
        updateUsers();
    }
    
    private void updateUsers(){
        for(int i = 0; i < connectionList.size(); i++){
            ServerThread serverThread = (ServerThread) connectionList.get(i);
            serverThread.sendUserMap(userMap);
        }
    }
    
    public UserMap getUserMap(){
        return userMap;
    }
}
            